package com.ruoyi.match.match.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.match.dto.OddsDto;
import com.ruoyi.match.enums.*;
import com.ruoyi.match.match.domain.HistoryMatchOddsChange;
import com.ruoyi.match.match.dto.ScorePriceDto;
import com.ruoyi.match.match.dto.SortDto;
import com.ruoyi.match.match.mapper.HistoryMatchOddsChangeMapper;
import com.ruoyi.match.match.service.CommonService;
import com.ruoyi.match.match.vo.*;
import com.ruoyi.match.match.vvo.Forecast;
import com.ruoyi.match.match.vvo.HistoryDataVO;
import com.ruoyi.match.match.vvo.MatchResultForecast;
import com.ruoyi.match.match.vvo.PriceSortVO;
import com.ruoyi.match.utils.OddsRangeUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import com.ruoyi.match.match.domain.bo.MatchBo;
import com.ruoyi.match.match.domain.vo.MatchVo;
import com.ruoyi.match.match.domain.Match;
import com.ruoyi.match.match.mapper.MatchMapper;
import com.ruoyi.match.match.service.IMatchService;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 比赛信息Service业务层处理
 *
 * @author sjz
 * @date 2023-11-03
 */
@RequiredArgsConstructor
@Service
public class MatchServiceImpl implements IMatchService {

    private final MatchMapper baseMapper;

    private final CommonService commonService;

    private final HistoryMatchOddsChangeMapper matchOddsChangeMapper;


    /**
     * 查询比赛信息
     */
    @Override
    public HistoryVO queryById(Long id,Boolean maxFlag){
        HistoryVO vo = new HistoryVO();
        baseInfo(vo,id);
        historyDataHandler(vo,maxFlag);

        rqHistoryDataHandler(vo,maxFlag);

        return vo;
    }

    @Override
    public MatchInfoVO getHistoryInfo(Long id) {
        MatchInfoVO matchInfoVO = new MatchInfoVO();
        // 比赛基本信息
        matchBaseInfoHandler(matchInfoVO,id);
        // 比赛赔率变化
        commonService.oddsChangeList(matchInfoVO);
        // 根据赔率计算分布信息
        commonService.distributedComputing(matchInfoVO);
        // 风险评估
        commonService.getOddRiskAssessment(matchInfoVO);
        // 让球胜负 分布
        commonService.letTheBallCalculate(matchInfoVO);
//        // 进球分布
//        commonService.jqDistributedComputing(matchInfoVO);
//        // 比分分布
//        commonService.scoreDistributedComputing(matchInfoVO);
        return matchInfoVO;
    }

    @Override
    public MatchInfoV2VO getHistoryInfoV2(Long id) {
        MatchInfoV2VO matchInfoVO = new MatchInfoV2VO();
        // 比赛基本信息
        matchBaseInfoHandlerV2(matchInfoVO,id);
        // 历史比分分布
        historyMatch(matchInfoVO);
        return matchInfoVO;
    }

    private void historyMatch(MatchInfoV2VO matchInfoVO) {
        List<Match> historyMatchList = getHistoryReverse2(matchInfoVO);
        Map<Integer, List<Match>> jqMap = historyMatchList.stream().collect(Collectors.groupingBy(Match::getJqNum));
        Map<Integer,List<List<MatchDistributionVO>>> historyMatchRangeList = new HashMap<>();

        List<Integer> collect1 = jqMap.keySet().stream().sorted().collect(Collectors.toList());

        for (Integer jqNum : collect1) {
            List<Match> matches = jqMap.get(jqNum);
            List<List<MatchDistributionVO>> collect = Lists.newArrayList();
            for (Match match : matches) {
                collect.add(getCurrentRangeList(match));
            }
            historyMatchRangeList.put(jqNum,collect);
        }
//        List<Integer> collect = historyMatchRangeList.keySet().stream().sorted().collect(Collectors.toList());
//        Map<String,List<List<MatchDistributionVO>>> sortHistoryMatchRangeList = new HashMap<>();
//        for (Integer s : collect) {
//            sortHistoryMatchRangeList.put(s,historyMatchRangeList.get(s));
//        }
        matchInfoVO.setHistoryMatchRangeList(historyMatchRangeList);
    }

    private List<Match> getHistoryReverse2(MatchInfoV2VO match) {
        List<Match> matches = Lists.newArrayList();
        OddsDto main = new OddsDto();
        main.setMin(match.getBaseInfo().getJcInitMain());
        main.setMax(match.getBaseInfo().getJcInitMain());
        OddsDto level = new OddsDto();
        OddsDto gust =  new OddsDto();
        matches   = baseMapper.selectListByInitOdds(main,level,gust,1);
        if (CollUtil.isNotEmpty(matches) && matches.size() > 50){
            return matches;
        }
        for (int i = 1; i <= 10; i++) {
            BigDecimal divide = new BigDecimal(i).divide(BigDecimal.TEN,1, RoundingMode.DOWN);
            main = OddsRangeUtil.getOddsRange2(match.getBaseInfo().getJcInitMain(), divide);
            matches   = baseMapper.selectListByInitOdds(main,level,gust,1);
            if (CollUtil.isNotEmpty(matches) && matches.size() > 50){
                break;
            }
        }
        return matches;
    }


    private void matchBaseInfoHandlerV2(MatchInfoV2VO matchInfoVO, Long id) {
        Match match = baseMapper.selectById(id);
        MatchBase2Info baseInfo = new MatchBase2Info();
        BeanUtil.copyProperties(match,baseInfo);
        matchInfoVO.setBaseInfo(baseInfo);
        // 当前比分 分布
        List<MatchDistributionVO> currentMatchRangeList = getCurrentRangeList(match);
        matchInfoVO.setCurrentMatchRangeList(currentMatchRangeList);

    }


    private void matchBaseInfoHandler(MatchInfoVO matchInfoVO, Long id) {
        Match match = baseMapper.selectById(id);
        MatchBaseInfo baseInfo = new MatchBaseInfo();
        BeanUtil.copyProperties(match,baseInfo);
        // 当前总求数 价格排序
        String currentJqSort = commonService.getMatchJqSortList(match);
        baseInfo.setCurrentJqSort(currentJqSort);

        matchInfoVO.setBaseInfo(baseInfo);
        // 当前比分 分布
        List<MatchDistributionVO> currentMatchRangeList = getCurrentRangeList(match);
        // 比分 让球 胜负
        matchInfoVO.setCurrentMatchRangeList(currentMatchRangeList);
    }




    private void rqHistoryDataHandler(HistoryVO vo,Boolean maxFlag) {
        Match match = vo.getMatch();
        List<Match> historyData = getRqHistory(match,maxFlag);

        // 让球 历史主胜数据
        List<Match> mainList = historyData.stream().filter(f->{
            String rq = f.getRq();
            String matchScore = f.getMatchScore();
            List<String> split = StrUtil.split(matchScore, ":");
            String mainJq = split.get(0);
            String gustJq = split.get(1);

            BigDecimal a = new BigDecimal(mainJq);
            BigDecimal b = new BigDecimal(gustJq);
            BigDecimal c = new BigDecimal(rq);
            return a.add(c).compareTo(b) > 0 ;
        }).collect(Collectors.toList());
        HistoryDataVO rqMainVO = getHistoryDataVo(mainList);
        vo.setRqMainVO(rqMainVO);


        // 让球 历史平胜数据
        List<Match> levelList = historyData.stream().filter(f->{
            String rq = f.getRq();
            String matchScore = f.getMatchScore();
            List<String> split = StrUtil.split(matchScore, ":");
            String mainJq = split.get(0);
            String gustJq = split.get(1);

            BigDecimal a = new BigDecimal(mainJq);
            BigDecimal b = new BigDecimal(gustJq);
            BigDecimal c = new BigDecimal(rq);
            return a.add(c).compareTo(b) == 0 ;
        }).collect(Collectors.toList());
        HistoryDataVO rqLevelVO = getHistoryDataVo(levelList);
        vo.setRqLevelVO(rqLevelVO);


        // 让球 历史客胜数据
        List<Match> gustList = historyData.stream().filter(f->{
            String rq = f.getRq();
            String matchScore = f.getMatchScore();
            List<String> split = StrUtil.split(matchScore, ":");
            String mainJq = split.get(0);
            String gustJq = split.get(1);

            BigDecimal a = new BigDecimal(mainJq);
            BigDecimal b = new BigDecimal(gustJq);
            BigDecimal c = new BigDecimal(rq);
            return a.add(c).compareTo(b) < 0 ;
        }).collect(Collectors.toList());
        HistoryDataVO rqGustVO = getHistoryDataVo(gustList);
        vo.setRqGustVO(rqGustVO);


        // 反向数据
        List<Match> historyReverseData = getRqHistoryReverse(match,maxFlag);
        // 反向历史主胜数据
        List<Match> mainReverseList = historyReverseData.stream().filter(f->{
            String rq = f.getRq();
            String matchScore = f.getMatchScore();
            List<String> split = StrUtil.split(matchScore, ":");
            String mainJq = split.get(0);
            String gustJq = split.get(1);

            BigDecimal a = new BigDecimal(mainJq);
            BigDecimal b = new BigDecimal(gustJq);
            BigDecimal c = new BigDecimal(rq);
            return a.add(c).compareTo(b) > 0 ;
        }).collect(Collectors.toList());
        HistoryDataVO mainReverseVO = getHistoryDataVo(mainReverseList);
        vo.setRqMainReverseVO(mainReverseVO);
        // 反向历史平胜数据
        List<Match> levelReverseList = historyReverseData.stream().filter(f->{
            String rq = f.getRq();
            String matchScore = f.getMatchScore();
            List<String> split = StrUtil.split(matchScore, ":");
            String mainJq = split.get(0);
            String gustJq = split.get(1);

            BigDecimal a = new BigDecimal(mainJq);
            BigDecimal b = new BigDecimal(gustJq);
            BigDecimal c = new BigDecimal(rq);
            return a.add(c).compareTo(b) == 0 ;
        }).collect(Collectors.toList());
        HistoryDataVO levelReverseVO = getHistoryDataVo(levelReverseList);
        vo.setRqLevelReverseVO(levelReverseVO);
        // 反向历史客胜数据
        List<Match> gustReverseList = historyReverseData.stream().filter(f->{
            String rq = f.getRq();
            String matchScore = f.getMatchScore();
            List<String> split = StrUtil.split(matchScore, ":");
            String mainJq = split.get(0);
            String gustJq = split.get(1);

            BigDecimal a = new BigDecimal(mainJq);
            BigDecimal b = new BigDecimal(gustJq);
            BigDecimal c = new BigDecimal(rq);
            return a.add(c).compareTo(b) < 0 ;
        }).collect(Collectors.toList());
        HistoryDataVO gustReverseVO = getHistoryDataVo(gustReverseList);
        vo.setRqGustReverseVO(gustReverseVO);

        // 预测
        List<Forecast> rqJqForecastList = getJqForecast(vo.getCurrentJqSortList(),mainList,levelList,gustList);
        vo.setRqJqForecastList(rqJqForecastList);

        List<Forecast> rqHalfForecastList = getHalfForecast(vo.getHalfSortList(),mainList,levelList,gustList);
        vo.setRqHalfForecastList(rqHalfForecastList);


        List<Forecast> rqJqReverseForecastList = getJqForecast(vo.getCurrentJqSortList(),mainReverseList,levelReverseList,gustReverseList);
        vo.setRqJqReverseForecastList(rqJqReverseForecastList);

        List<Forecast> rqHalfReverseForecastList = getHalfForecast(vo.getHalfSortList(),mainReverseList,levelReverseList,gustReverseList);
        vo.setRqHalfReverseForecastList(rqHalfReverseForecastList);
    }

    private List<Match> getRqHistoryReverse(Match match,Boolean maxFlag) {
        OddsDto main = OddsRangeUtil.getOddsRange(match.getRqMainWinOdds());
        OddsDto level = OddsRangeUtil.getOddsRange(match.getRqLevelOdds());
        OddsDto gust = OddsRangeUtil.getOddsRange(match.getRqGustWinOdds());
        if(maxFlag){
            main.setMin(main.getMin().subtract(new BigDecimal("0.5")));
            main.setMax(main.getMax().add(new BigDecimal("0.5")));

            level.setMin(level.getMin().subtract(new BigDecimal("0.5")));
            level.setMax(level.getMax().add(new BigDecimal("0.5")));

            gust.setMin(gust.getMin().subtract(new BigDecimal("0.5")));
            gust.setMax(gust.getMax().add(new BigDecimal("0.5")));
        }
        String rq = match.getRq();
        return baseMapper.selectList(Wrappers.<Match>lambdaQuery()
            .eq(Match::getRq,rq)
            .ge(Match::getRqGustWinOdds, main.getMin())
            .le(Match::getRqGustWinOdds, main.getMax())
            .ge(Match::getRqLevelOdds, level.getMin())
            .le(Match::getRqLevelOdds, level.getMax())
            .ge(Match::getRqMainWinOdds, gust.getMin())
            .le(Match::getRqMainWinOdds, gust.getMax())
            .isNotNull(Match::getMatchHalfResult));
    }

    private List<Match> getRqHistory(Match match,Boolean maxFlag) {
        OddsDto main = OddsRangeUtil.getOddsRange(match.getRqMainWinOdds());
        OddsDto level = OddsRangeUtil.getOddsRange(match.getRqLevelOdds());
        OddsDto gust = OddsRangeUtil.getOddsRange(match.getRqGustWinOdds());
        if(maxFlag){
            main.setMin(main.getMin().subtract(new BigDecimal("0.5")));
            main.setMax(main.getMax().add(new BigDecimal("0.5")));

            level.setMin(level.getMin().subtract(new BigDecimal("0.5")));
            level.setMax(level.getMax().add(new BigDecimal("0.5")));

            gust.setMin(gust.getMin().subtract(new BigDecimal("0.5")));
            gust.setMax(gust.getMax().add(new BigDecimal("0.5")));
        }
        String rq = match.getRq();
        return baseMapper.selectList(Wrappers.<Match>lambdaQuery()
            .eq(Match::getRq,rq)
            .ge(Match::getRqMainWinOdds, main.getMin())
            .le(Match::getRqMainWinOdds, main.getMax())
            .ge(Match::getRqLevelOdds, level.getMin())
            .le(Match::getRqLevelOdds, level.getMax())
            .ge(Match::getRqGustWinOdds, gust.getMin())
            .le(Match::getRqGustWinOdds, gust.getMax())
            .isNotNull(Match::getMatchHalfResult));
    }

    private void historyDataHandler(HistoryVO vo,Boolean maxFlag) {
        Match match = vo.getMatch();
        List<Match> historyData = getHistory(match,maxFlag);

        // 历史主胜数据
        List<Match> mainList = historyData.stream().filter(f->MatchResult.MAIN.getIndex().equals(f.getMatchResult())).collect(Collectors.toList());
        HistoryDataVO mainVO = getHistoryDataVo(mainList);
        vo.setMainVO(mainVO);
        // 历史平胜数据
        List<Match> levelList = historyData.stream().filter(f->MatchResult.LEVEL.getIndex().equals(f.getMatchResult())).collect(Collectors.toList());
        HistoryDataVO levelVO = getHistoryDataVo(levelList);
        vo.setLevelVO(levelVO);
        // 历史客胜数据
        List<Match> gustList = historyData.stream().filter(f->MatchResult.GUST.getIndex().equals(f.getMatchResult())).collect(Collectors.toList());
        HistoryDataVO gustVO = getHistoryDataVo(gustList);
        vo.setGustVO(gustVO);

        // 反向数据
        List<Match> historyReverseData = getHistoryReverse(match,maxFlag);
        // 反向历史主胜数据
        List<Match> mainReverseList = historyReverseData.stream().filter(f->MatchResult.MAIN.getIndex().equals(f.getMatchResult())).collect(Collectors.toList());
        HistoryDataVO mainReverseVO = getHistoryDataVo(mainReverseList);
        vo.setMainReverseVO(mainReverseVO);
        // 反向历史平胜数据
        List<Match> levelReverseList = historyReverseData.stream().filter(f->MatchResult.LEVEL.getIndex().equals(f.getMatchResult())).collect(Collectors.toList());
        HistoryDataVO levelReverseVO = getHistoryDataVo(levelReverseList);
        vo.setLevelReverseVO(levelReverseVO);
        // 反向历史客胜数据
        List<Match> gustReverseList = historyReverseData.stream().filter(f->MatchResult.GUST.getIndex().equals(f.getMatchResult())).collect(Collectors.toList());
        HistoryDataVO gustReverseVO = getHistoryDataVo(gustReverseList);
        vo.setGustReverseVO(gustReverseVO);

        // 预测
        List<Forecast> jqForecastList = getJqForecast(vo.getCurrentJqSortList(),mainList,levelList,gustList);
        vo.setJqForecastList(jqForecastList);

        List<Forecast> jqReverseForecastList = getJqForecast(vo.getCurrentJqSortList(),mainReverseList,levelReverseList,gustReverseList);
        vo.setJqReverseForecastList(jqReverseForecastList);

        List<Forecast> halfForecastList = getHalfForecast(vo.getHalfSortList(),mainList,levelList,gustList);
        vo.setHalfForecastList(halfForecastList);

        List<Forecast> halfReverseForecastList = getHalfForecast(vo.getHalfSortList(),mainReverseList,levelReverseList,gustReverseList);
        vo.setHalfReverseForecastList(halfReverseForecastList);
    }

    private void baseInfo(HistoryVO vo, Long id) {
        Match match = baseMapper.selectById(id);
        // 比赛基本信息
        vo.setMatch(match);
        // 当前比分 分布
        List<MatchDistributionVO> currentMatchRangeList = getCurrentRangeList(match);
        vo.setCurrentMatchRangeList(currentMatchRangeList);
        // 当前比分   价格排序
        List<SortDto> matchScoreSort = getCurrentScoreSortList(match);
        vo.setMatchScoreSort(matchScoreSort);
        // 当前总求数 价格排序
        List<SortDto> currentJqSortList = getCurrentJqSortList(match);
        vo.setCurrentJqSortList(currentJqSortList);
        String currentJqSortStr = currentJqSortList.stream().sorted(Comparator.comparing(SortDto::getValue)).map(SortDto::getName).collect(Collectors.joining("->"));
        vo.setCurrentJqSortStr(currentJqSortStr);
        // 当前半场 价格排序
        List<SortDto> halfSortList = getCurrentHalfSortList(match);
        vo.setHalfSortList(halfSortList);

    }

    private List<Match> getHistoryReverse(Match match,Boolean maxFlag) {
        OddsDto main = null;
        OddsDto level = null;
        OddsDto gust = null;
        List<Match> matches = Lists.newArrayList();
        List<Match> filterMatches = Lists.newArrayList();
        for (int i = 1; i <= 10; i++) {
            BigDecimal divide = new BigDecimal(i).divide(BigDecimal.TEN,1, RoundingMode.DOWN);
            main = OddsRangeUtil.getOddsRange2(match.getRqMainWinOdds(),divide);
            level = OddsRangeUtil.getOddsRange2(match.getRqLevelOdds(),divide);
            gust = OddsRangeUtil.getOddsRange2(match.getRqGustWinOdds(),divide);
            matches   = baseMapper.selectListByInitOdds(gust,level,main,1);
            if (CollUtil.isNotEmpty(matches) && matches.size() > 50){
                break;
            }
        }
        return filterMatches;
    }

    private List<Forecast> getHalfForecast(List<SortDto> hfs, List<Match> mainList, List<Match> levelList, List<Match> gustList) {
        List<Forecast> result = Lists.newArrayList();
        for (int endIndex = 2; endIndex < hfs.size(); endIndex++) {

            StringJoiner stringJoiner = new StringJoiner("-");
            for (int startIndex = 0; startIndex < endIndex; startIndex++) {
                stringJoiner.add(hfs.get(startIndex).getName());
            }
            String matchSocreStr = stringJoiner.toString();

            BigDecimal main = BigDecimal.ZERO;
            BigDecimal level = BigDecimal.ZERO;
            BigDecimal gust = BigDecimal.ZERO;

            int finalEndIndex = endIndex;
            Map<String, List<Match>> mainMap = mainList.stream().collect(Collectors.groupingBy(g -> {
                List<SortDto> currentJqSortList = getCurrentHalfSortList(g);
                StringJoiner sj = new StringJoiner("-");
                for (int i = 0; i < finalEndIndex ; i++) {
                    sj.add(currentJqSortList.get(i).getName());
                }
                return sj.toString();
            }));
            // 按照进球数 进行 分组 主胜的 数量是
            if (mainMap.containsKey(matchSocreStr)) {
                int size = mainMap.get(matchSocreStr).size();
                main = new BigDecimal(size);
            }

            Map<String, List<Match>> levelMap = levelList.stream().collect(Collectors.groupingBy(g -> {
                List<SortDto> currentJqSortList = getCurrentHalfSortList(g);
                StringJoiner sj = new StringJoiner("-");
                for (int i = 0; i < finalEndIndex; i++) {
                    sj.add(currentJqSortList.get(i).getName());
                }
                return sj.toString();
            }));
            if (levelMap.containsKey(matchSocreStr)) {
                int size = levelMap.get(matchSocreStr).size();
                level = new BigDecimal(size);
            }

            Map<String, List<Match>> gustMap = gustList.stream().collect(Collectors.groupingBy(g -> {
                List<SortDto> currentJqSortList = getCurrentHalfSortList(g);
                StringJoiner sj = new StringJoiner("-");
                for (int i = 0; i < finalEndIndex; i++) {
                    sj.add(currentJqSortList.get(i).getName());
                }
                return sj.toString();
            }));

            if (gustMap.containsKey(matchSocreStr)) {
                int size = gustMap.get(matchSocreStr).size();
                gust = new BigDecimal(size);
            }
            Forecast forecast  = new Forecast();
            forecast.setName(String.format("按照半场顺序前%d,排序",endIndex+1));
            BigDecimal total = main.add(level).add(gust);
            MatchResultForecast resultForecast = new MatchResultForecast();
            if(total.compareTo(BigDecimal.ZERO) > 0){
                resultForecast.setMainNum(main.intValue());
                resultForecast.setMainWinOdds(main.divide(total,2, RoundingMode.DOWN));
                resultForecast.setLevelNum(level.intValue());
                resultForecast.setLevelWinOdds(level.divide(total,2, RoundingMode.DOWN));
                resultForecast.setGustNum(gust.intValue());
                resultForecast.setGustWinOdds(gust.divide(total,2, RoundingMode.DOWN));
            }
            forecast.setResultForecast(resultForecast);
            result.add(forecast);
        }
        return result;
    }

    private List<Forecast> getJqForecast(List<SortDto> cjs, List<Match> mainList, List<Match> levelList, List<Match> gustList) {
        List<Forecast> result = Lists.newArrayList();
        for (int endIndex = 2; endIndex < cjs.size(); endIndex++) {

            StringJoiner stringJoiner = new StringJoiner("-");
            for (int startIndex = 0; startIndex < endIndex; startIndex++) {
                stringJoiner.add(cjs.get(startIndex).getName());
            }
            String matchSocreStr = stringJoiner.toString();

            BigDecimal main = BigDecimal.ZERO;
            BigDecimal level = BigDecimal.ZERO;
            BigDecimal gust = BigDecimal.ZERO;

            int finalEndIndex = endIndex;
            Map<String, List<Match>> mainMap = mainList.stream().collect(Collectors.groupingBy(g -> {
                List<SortDto> currentJqSortList = getCurrentJqSortList(g);
                StringJoiner sj = new StringJoiner("-");
                for (int i = 0; i < finalEndIndex ; i++) {
                    sj.add(currentJqSortList.get(i).getName());
                }
                return sj.toString();
            }));
            // 按照进球数 进行 分组 主胜的 数量是
            if (mainMap.containsKey(matchSocreStr)) {
                int size = mainMap.get(matchSocreStr).size();
                main = new BigDecimal(size);
            }

            Map<String, List<Match>> levelMap = levelList.stream().collect(Collectors.groupingBy(g -> {
                List<SortDto> currentJqSortList = getCurrentJqSortList(g);
                StringJoiner sj = new StringJoiner("-");
                for (int i = 0; i < finalEndIndex; i++) {
                    sj.add(currentJqSortList.get(i).getName());
                }
                return sj.toString();
            }));
            if (levelMap.containsKey(matchSocreStr)) {
                int size = levelMap.get(matchSocreStr).size();
                level = new BigDecimal(size);
            }

            Map<String, List<Match>> gustMap = gustList.stream().collect(Collectors.groupingBy(g -> {
                List<SortDto> currentJqSortList = getCurrentJqSortList(g);
                StringJoiner sj = new StringJoiner("-");
                for (int i = 0; i < finalEndIndex; i++) {
                    sj.add(currentJqSortList.get(i).getName());
                }
                return sj.toString();
            }));

            if (gustMap.containsKey(matchSocreStr)) {
                int size = gustMap.get(matchSocreStr).size();
                gust = new BigDecimal(size);
            }
            Forecast forecast  = new Forecast();
            forecast.setName(String.format("按照进球顺序前%d,排序",endIndex+1));
            BigDecimal total = main.add(level).add(gust);
            MatchResultForecast resultForecast = new MatchResultForecast();
            if(total.compareTo(BigDecimal.ZERO) > 0){
                resultForecast.setMainNum(main.intValue());
                resultForecast.setMainWinOdds(main.divide(total,2, RoundingMode.DOWN));
                resultForecast.setLevelNum(level.intValue());
                resultForecast.setLevelWinOdds(level.divide(total,2, RoundingMode.DOWN));
                resultForecast.setGustNum(gust.intValue());
                resultForecast.setGustWinOdds(gust.divide(total,2, RoundingMode.DOWN));
            }
            forecast.setResultForecast(resultForecast);
            result.add(forecast);
        }
        return result;
    }

    private HistoryDataVO getHistoryDataVo(List<Match> matchList) {
        HistoryDataVO historyDataVO = new HistoryDataVO();
        // 自定义区间 比分 分布
//        List<MatchDistributionVO> scoreDistribution = getCustomScoreDistribution(matchList);
        // 所有 中将的 比分 分布
        List<MatchDistributionNumVO> scoreList = getScoreDistribution(matchList);
        historyDataVO.setScoreList(scoreList);
        // 所有 中将的 总球数 分布
        List<MatchDistributionNumVO> jqList = getJqDistribution(matchList);
        historyDataVO.setJqList(jqList);
        // 所有 中将的 半场 分布
        List<MatchDistributionNumVO> halfList = getHalfDistribution(matchList);
        historyDataVO.setHalfList(halfList);
        //
        List<PriceSortVO> sortList = Lists.newArrayList();
        for (Match match : matchList) {
            PriceSortVO sortVO = new PriceSortVO();
            // 比分
            String matchScore = match.getMatchScore();
            sortVO.setScore(matchScore);
            // 进球数
            int num = getJqResultByScore(matchScore);
            sortVO.setJqNum(num);
            // 半场
            String matchHalfResult = match.getMatchHalfResult();
            sortVO.setHalf(matchHalfResult);

            // 中将比分 赔率 排名
            int scoreSortIndex = getScoreSortIndex(match);
            sortVO.setScoreRanking(scoreSortIndex);
            // 中将进球数 赔率 排名
            int jqSortIndex = getJqSortIndex(match);
            sortVO.setJqNumRanking(jqSortIndex);
            // 中将半场 赔率排名
            int halfSortIndex = getHalfSortIndex(match);
            sortVO.setHalfRanking(halfSortIndex);
            sortVO.setRanking(String.format("%d-%d-%d",jqSortIndex,halfSortIndex,scoreSortIndex));
            sortList.add(sortVO);
        }
        Map<Integer, List<PriceSortVO>> scoreMap = sortList.stream().collect(Collectors.groupingBy(PriceSortVO::getScoreRanking));
        List<MatchDistributionNumVO> scoreSortList = Lists.newArrayList();
        for (Integer s : scoreMap.keySet()) {
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            vo.setLabel(String.format("比分价格排名第%s",s));
            vo.setNum(scoreMap.get(s).size());
            scoreSortList.add(vo);
        }
        historyDataVO.setScoreSortList(scoreSortList.stream().sorted(Comparator.comparing(MatchDistributionNumVO::getNum).reversed()).collect(Collectors.toList()));

        Map<Integer, List<PriceSortVO>> jqMap = sortList.stream().collect(Collectors.groupingBy(PriceSortVO::getJqNumRanking));
        List<MatchDistributionNumVO> jqSortList = Lists.newArrayList();
        for (Integer s : jqMap.keySet()) {
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            vo.setLabel(String.format("进球价格排名第%s",s));
            vo.setNum(jqMap.get(s).size());
            jqSortList.add(vo);
        }
        historyDataVO.setJqSortList(jqSortList.stream().sorted(Comparator.comparing(MatchDistributionNumVO::getNum).reversed()).collect(Collectors.toList()));

        Map<Integer, List<PriceSortVO>> halfMap = sortList.stream().collect(Collectors.groupingBy(PriceSortVO::getHalfRanking));
        List<MatchDistributionNumVO> halfSortList = Lists.newArrayList();
        for (Integer s : halfMap.keySet()) {
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            vo.setLabel(String.format("半场价格排名第%s",s));
            vo.setNum(halfMap.get(s).size());
            halfSortList.add(vo);
        }
        historyDataVO.setHalfSortList(halfSortList.stream().sorted(Comparator.comparing(MatchDistributionNumVO::getNum).reversed()).collect(Collectors.toList()));

        Map<String, List<PriceSortVO>> rankingMap = sortList.stream().collect(Collectors.groupingBy(PriceSortVO::getRanking));
        List<MatchDistributionNumVO> rankSortList = Lists.newArrayList();
        for (String s : rankingMap.keySet()) {
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            vo.setLabel(s);
            vo.setNum(rankingMap.get(s).size());
            rankSortList.add(vo);
        }
        historyDataVO.setRankSortList(rankSortList.stream().sorted(Comparator.comparing(MatchDistributionNumVO::getNum).reversed()).collect(Collectors.toList()));
        return historyDataVO;
    }

    private int getHalfSortIndex(Match match) {
        List<SortDto> currentHalfSortList = getCurrentHalfSortList(match);
        int i =1;
        for (SortDto dto : currentHalfSortList) {
            if(dto.getResult()){
                break;
            }
            i++;
        }
        return i;
    }

    private int getJqSortIndex(Match match) {
        List<SortDto> currentJqSortList = getCurrentJqSortList(match);
        int i =1;
        for (SortDto dto : currentJqSortList) {
            if(dto.getResult()){
                break;
            }
            i++;
        }
        return i;
    }

    private int getScoreSortIndex(Match match) {
        List<SortDto> currentScoreSortList = getCurrentScoreSortList(match);
        int i =1;
        for (SortDto dto : currentScoreSortList) {
            if(dto.getResult()){
                break;
            }
            i++;
        }
        return i;
    }

    private List<MatchDistributionNumVO> getScoreDistribution(List<Match> matchList) {
        List<MatchDistributionNumVO> scoreList = Lists.newArrayList();
        Map<String, List<MatchDistributionNumVO>> dataMap = matchList.stream().map(m -> {
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            String matchScore = m.getMatchScore();
            ScoreEnum scoreEnum = ScoreEnum.getScoreByMatchScoreResult(matchScore);
            assert scoreEnum != null;
            vo.setLabel(scoreEnum.getCode());
            vo.setNum(1);
            ScorePriceDto scorePriceDto = ScoreEnum.getScorePriceDto(m, m.getMatchScore());
            vo.setPrice(scorePriceDto.getPrice());
            List<BigDecimal> priceList = Lists.newArrayList();
            priceList.add(scorePriceDto.getPrice());
            vo.setPriceList(priceList);
            return vo;
        }).collect(Collectors.groupingBy(MatchDistributionNumVO::getLabel));
        for (String s : dataMap.keySet()) {
            List<MatchDistributionNumVO> matchDistributionNumVOList = dataMap.get(s);
            List<BigDecimal> priceList = matchDistributionNumVOList.stream().flatMap(f -> f.getPriceList().stream()).distinct().sorted().collect(Collectors.toList());
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            vo.setLabel(s);
            vo.setNum(dataMap.get(s).size());
            vo.setMinPrice(CollUtil.getFirst(priceList));
            vo.setMaxPrice(CollUtil.getLast(priceList));
            vo.setPriceList(priceList);
            scoreList.add(vo);
        }
        return scoreList.stream().sorted(Comparator.comparing(MatchDistributionNumVO::getNum).reversed()).collect(Collectors.toList());
    }

    private List<MatchDistributionNumVO> getHalfDistribution(List<Match> matchList) {
        List<MatchDistributionNumVO> halfList = Lists.newArrayList();
        Map<String, List<MatchDistributionNumVO>> dataMap = matchList.stream().map(m -> {
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            String matchHalfResult = m.getMatchHalfResult();
            HalfEnum halfEnum = HalfEnum.getHalfByMatchHalfResult(matchHalfResult);
            assert halfEnum != null;
            vo.setLabel(halfEnum.getCode());
            vo.setNum(1);
            return vo;
        }).collect(Collectors.groupingBy(MatchDistributionNumVO::getLabel));
        for (String s : dataMap.keySet()) {
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            vo.setLabel(s);
            vo.setNum(dataMap.get(s).size());
            halfList.add(vo);
        }
        return halfList.stream().sorted(Comparator.comparing(MatchDistributionNumVO::getNum).reversed()).collect(Collectors.toList());
    }

    private List<MatchDistributionNumVO> getJqDistribution(List<Match> matchList) {
        List<MatchDistributionNumVO> jqList = Lists.newArrayList();
        Map<String, List<MatchDistributionNumVO>> dataMap = matchList.stream().map(m -> {
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            String matchScore = m.getMatchScore();
            int num = getJqResultByScore(matchScore);
            JqEnum jq = JqEnum.getJqByNum(num);
            assert jq != null;
            vo.setLabel(jq.getCode());
            vo.setNum(1);
            return vo;
        }).collect(Collectors.groupingBy(MatchDistributionNumVO::getLabel));
        for (String s : dataMap.keySet()) {
            MatchDistributionNumVO vo = new MatchDistributionNumVO();
            vo.setLabel(s);
            vo.setNum(dataMap.get(s).size());
            jqList.add(vo);
        }
        return jqList.stream().sorted(Comparator.comparing(MatchDistributionNumVO::getNum).reversed()).collect(Collectors.toList());
    }

//    private List<MatchDistributionVO> getCustomScoreDistribution(List<Match> matchList) {
//        List<MatchDistributionVO> resultList = Lists.newArrayList();
//        for (CsValueEnum value : CsValueEnum.values()) {
//            MatchDistributionVO vo = new MatchDistributionVO();
//            vo.setType(value.getDesc());
//            List<MatchDistributionNumVO> csList = getMatchScoreDistributionNum(matchList,value);
//            vo.setCsList(csList.stream().sorted(Comparator.comparing(MatchDistributionNumVO::getNum).reversed()).collect(Collectors.toList()));
//            resultList.add(vo);
//        }
//        return resultList;
//    }

    private List<MatchDistributionNumVO> getMatchScoreDistributionNum(List<Match> matchList,
                                                                      CsValueEnum value) {

        List<MatchDistributionNumVO> csVOList = Lists.newArrayList();
        for (Match match : matchList) {
            BigDecimal min = value.getMin();
            BigDecimal max = value.getMax();

            BigDecimal cs01 = match.getCs01();
            if(cs01.compareTo(min) >= 0 && cs01.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_0_1,csVOList,cs01);
            }
            BigDecimal cs02 = match.getCs02();
            if(cs02.compareTo(min) >= 0 && cs02.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_0_2,csVOList,cs02);
            }
            BigDecimal cs03 = match.getCs03();
            if(cs03.compareTo(min) >= 0 && cs03.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_0_3,csVOList,cs03);
            }
            BigDecimal cs04 = match.getCs04();
            if(cs04.compareTo(min) >= 0 && cs04.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_0_4,csVOList,cs04);
            }
            BigDecimal cs05 = match.getCs05();
            if(cs05.compareTo(min) >= 0 && cs05.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_0_5,csVOList,cs05);
            }

            BigDecimal cs10 = match.getCs10();
            if(cs10.compareTo(min) >= 0 && cs10.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_1_0,csVOList,cs10);
            }
            BigDecimal cs12 = match.getCs12();
            if(cs12.compareTo(min) >= 0 && cs12.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_1_2,csVOList,cs12);
            }
            BigDecimal cs13 = match.getCs13();
            if(cs13.compareTo(min) >= 0 && cs13.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_1_3,csVOList,cs13);
            }

            BigDecimal cs14 = match.getCs14();
            if(cs14.compareTo(min) >= 0 && cs14.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_1_4,csVOList,cs14);
            }

            BigDecimal cs15 = match.getCs15();
            if(cs15.compareTo(min) >= 0 && cs15.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_1_5,csVOList,cs15);
            }

            BigDecimal cs20 = match.getCs20();
            if(cs20.compareTo(min) >= 0 && cs20.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_2_0,csVOList,cs20);
            }

            BigDecimal cs21 = match.getCs21();

            if(cs21.compareTo(min) >= 0 && cs21.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_2_1,csVOList,cs21);
            }

            BigDecimal cs23 = match.getCs23();
            if(cs23.compareTo(min) >= 0 && cs23.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_2_3,csVOList,cs23);
            }

            BigDecimal cs24 = match.getCs24();
            if(cs24.compareTo(min) >= 0 && cs24.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_2_4,csVOList,cs24);
            }

            BigDecimal cs25 = match.getCs25();
            if(cs25.compareTo(min) >= 0 && cs25.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_2_5,csVOList,cs25);
            }

            BigDecimal cs30 = match.getCs30();
            if(cs30.compareTo(min) >= 0 && cs30.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_3_0,csVOList,cs30);
            }

            BigDecimal cs31 = match.getCs31();
            if(cs31.compareTo(min) >= 0 && cs31.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_3_1,csVOList,cs31);
            }

            BigDecimal cs32 = match.getCs32();
            if(cs32.compareTo(min) >= 0 && cs32.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_3_2,csVOList,cs32);
            }
            BigDecimal cs40 = match.getCs40();
            if(cs40.compareTo(min) >= 0 && cs40.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_4_0,csVOList,cs40);
            }
            BigDecimal cs41 = match.getCs41();
            if(cs41.compareTo(min) >= 0 && cs41.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_4_1,csVOList,cs41);
            }

            BigDecimal cs42 = match.getCs42();
            if(cs42.compareTo(min) >= 0 && cs42.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_4_2,csVOList,cs42);
            }

            BigDecimal cs50 = match.getCs50();
            if(cs50.compareTo(min) >= 0 && cs50.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_5_0,csVOList,cs50);
            }
            BigDecimal cs51 = match.getCs51();
            if(cs51.compareTo(min) >= 0 && cs51.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_5_1,csVOList,cs51);
            }

            BigDecimal cs52 = match.getCs42();
            if(cs52.compareTo(min) >= 0 && cs52.compareTo(max) < 0){
                addCsVo(ScoreEnum.CS_5_2,csVOList,cs52);
            }

            BigDecimal level00 = match.getLevel00();
            if(level00.compareTo(min) >= 0 && level00.compareTo(max) < 0){
                addCsVo(ScoreEnum.LEVEL_0_0,csVOList,level00);
            }

            BigDecimal level11 = match.getLevel11();
            if(level11.compareTo(min) >= 0 && level11.compareTo(max) < 0){
                addCsVo(ScoreEnum.LEVEL_1_1,csVOList,level11);
            }
            BigDecimal level22 = match.getLevel22();
            if(level22.compareTo(min) >= 0 && level22.compareTo(max) < 0){
                addCsVo(ScoreEnum.LEVEL_2_2,csVOList,level22);
            }
            BigDecimal level33 = match.getLevel33();
            if(level33.compareTo(min) >= 0 && level33.compareTo(max) < 0){
                addCsVo(ScoreEnum.LEVEL_3_3,csVOList,level33);
            }

            BigDecimal winOther = match.getWinOther();
            if(winOther.compareTo(min) >= 0 && winOther.compareTo(max) < 0){
                addCsVo(ScoreEnum.WIN_OTHER,csVOList,winOther);
            }

            BigDecimal levelOther = match.getLevelOther();
            if(levelOther.compareTo(min) >= 0 && levelOther.compareTo(max) < 0){
                addCsVo(ScoreEnum.LEVEL_OTHER,csVOList,levelOther);
            }

            BigDecimal lostOther = match.getLostOther();
            if(lostOther.compareTo(min) >= 0 && lostOther.compareTo(max) < 0){
                addCsVo(ScoreEnum.LOST_OTHER,csVOList,lostOther);
            }
        }
        return csVOList;
    }

    private List<Match> getHistory(Match match,Boolean maxFlag) {
        OddsDto main = null;
        OddsDto level = null;
        OddsDto gust = null;
        List<Match> matches = Lists.newArrayList();
        List<Match> filterMatches = Lists.newArrayList();
        for (int i = 1; i <= 10; i++) {
            BigDecimal divide = new BigDecimal(i).divide(BigDecimal.TEN,1, RoundingMode.DOWN);
            main = OddsRangeUtil.getOddsRange2(match.getRqMainWinOdds(),divide);
            level = OddsRangeUtil.getOddsRange2(match.getRqLevelOdds(),divide);
            gust = OddsRangeUtil.getOddsRange2(match.getRqGustWinOdds(),divide);
            matches   = baseMapper.selectListByInitOdds(main,level,gust,1);
            if (CollUtil.isNotEmpty(matches) && matches.size() > 50){
                break;
            }
        }
        return filterMatches;
    }

    private List<SortDto> getCurrentHalfSortList(Match match) {
        List<SortDto> resultList = Lists.newArrayList();
        for (HalfEnum value : HalfEnum.values()) {
            switch (value){
                case SS:
                    resultList.add(getHalfSortDto(value,match.getSs(),match.getMatchHalfResult().equals(value.getIndex())));
                    break;
                case SP:
                    resultList.add(getHalfSortDto(value,match.getSp(),match.getMatchHalfResult().equals(value.getIndex())));
                    break;
                case SF:
                    resultList.add(getHalfSortDto(value,match.getSf(),match.getMatchHalfResult().equals(value.getIndex())));
                    break;
                case PS:
                    resultList.add(getHalfSortDto(value,match.getPs(),match.getMatchHalfResult().equals(value.getIndex())));
                    break;
                case PP:
                    resultList.add(getHalfSortDto(value,match.getPp(),match.getMatchHalfResult().equals(value.getIndex())));
                    break;
                case PF:
                    resultList.add(getHalfSortDto(value,match.getPf(),match.getMatchHalfResult().equals(value.getIndex())));
                    break;
                case FS:
                    resultList.add(getHalfSortDto(value,match.getFs(),match.getMatchHalfResult().equals(value.getIndex())));
                    break;
                case FP:
                    resultList.add(getHalfSortDto(value,match.getFp(),match.getMatchHalfResult().equals(value.getIndex())));
                    break;
                case FF:
                    resultList.add(getHalfSortDto(value,match.getFf(),match.getMatchHalfResult().equals(value.getIndex())));
                    break;
            }
        }
        return resultList.stream().sorted(Comparator.comparing(SortDto::getValue)).collect(Collectors.toList());
    }

    private SortDto getHalfSortDto(HalfEnum value, BigDecimal half, boolean result) {
        SortDto dto = new SortDto();
        dto.setName(value.name());
        dto.setValue(half);
        dto.setResult(result);
        return dto;
    }

    private List<SortDto> getCurrentScoreSortList(Match match) {
        List<SortDto> resultList = Lists.newArrayList();
        for (ScoreEnum value : ScoreEnum.values()) {
            switch (value){
                case CS_0_1:
                    resultList.add(getCsSortDto(value,match.getCs01(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_0_2:
                    resultList.add(getCsSortDto(value,match.getCs02(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_0_3:
                    resultList.add(getCsSortDto(value,match.getCs03(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_0_4:
                    resultList.add(getCsSortDto(value,match.getCs04(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_0_5:
                    resultList.add(getCsSortDto(value,match.getCs05(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_1_0:
                    resultList.add(getCsSortDto(value,match.getCs10(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_1_2:
                    resultList.add(getCsSortDto(value,match.getCs12(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_1_3:
                    resultList.add(getCsSortDto(value,match.getCs13(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_1_4:
                    resultList.add(getCsSortDto(value,match.getCs14(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_1_5:
                    resultList.add(getCsSortDto(value,match.getCs15(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_2_0:
                    resultList.add(getCsSortDto(value,match.getCs20(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_2_1:
                    resultList.add(getCsSortDto(value,match.getCs21(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_2_3:
                    resultList.add(getCsSortDto(value,match.getCs23(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_2_4:
                    resultList.add(getCsSortDto(value,match.getCs24(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_2_5:
                    resultList.add(getCsSortDto(value,match.getCs25(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_3_0:
                    resultList.add(getCsSortDto(value,match.getCs30(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_3_1:
                    resultList.add(getCsSortDto(value,match.getCs31(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_3_2:
                    resultList.add(getCsSortDto(value,match.getCs32(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_4_0:
                    resultList.add(getCsSortDto(value,match.getCs40(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_4_1:
                    resultList.add(getCsSortDto(value,match.getCs41(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_4_2:
                    resultList.add(getCsSortDto(value,match.getCs42(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_5_0:
                    resultList.add(getCsSortDto(value,match.getCs50(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_5_1:
                    resultList.add(getCsSortDto(value,match.getCs51(),match.getMatchScore().equals(value.getCode())));
                    break;
                case CS_5_2:
                    resultList.add(getCsSortDto(value,match.getCs52(),match.getMatchScore().equals(value.getCode())));
                    break;
                case LEVEL_0_0:
                    resultList.add(getCsSortDto(value,match.getLevel00(),match.getMatchScore().equals(value.getCode())));
                    break;
                case LEVEL_1_1:
                    resultList.add(getCsSortDto(value,match.getLevel11(),match.getMatchScore().equals(value.getCode())));
                    break;
                case LEVEL_2_2:
                    resultList.add(getCsSortDto(value,match.getLevel22(),match.getMatchScore().equals(value.getCode())));
                    break;
                case LEVEL_3_3:
                    resultList.add(getCsSortDto(value,match.getLevel33(),match.getMatchScore().equals(value.getCode())));
                    break;
                case LEVEL_OTHER:
                    resultList.add(getCsSortDto(value,match.getLevelOther(),match.getMatchScore().equals(value.getCode())));
                    break;
                case WIN_OTHER:
                    resultList.add(getCsSortDto(value,match.getWinOther(),match.getMatchScore().equals(value.getCode())));
                    break;
                case LOST_OTHER:
                    resultList.add(getCsSortDto(value,match.getLostOther(),match.getMatchScore().equals(value.getCode())));
                    break;
            }
        }
        return resultList.stream().sorted(Comparator.comparing(SortDto::getValue)).collect(Collectors.toList());
    }
    private SortDto getCsSortDto(ScoreEnum value, BigDecimal cs,Boolean result) {
        SortDto dto = new SortDto();
        dto.setName(value.name());
        dto.setValue(cs);
        dto.setResult(result);
        return dto;
    }

//    private void rangeWinOdds(List<MatchDistributionVO> currentMatchRangeList, com.ruoyi.match.match.vo.HistoryVO vo) {
//        List<RangDto> rangeDtoList = Lists.newArrayList();
//        List<String> scoreList = ScoreEnum.getListByIndex(4);
//
//        for (MatchDistributionVO matchDistributionVO : currentMatchRangeList) {
//            String range = matchDistributionVO.getRange();
//            for (MatchStatisticsVO ms : vo.getMsList()) {
//                String title = ms.getTitle();
//                List<MatchDistributionVO> rangeList = ms.getRangeList();
//                List<MatchDistributionVO> collect = rangeList.stream().filter(f -> f.getRange().equals(range)).collect(Collectors.toList());
//                int sum = collect.stream().flatMap(ff -> ff.getCsList().stream()).filter(fil -> scoreList.contains(fil.getCs())).mapToInt(MatchDistributionNumVO::getNum).sum();
//                Optional<RangDto> first = rangeDtoList.stream().filter(f -> f.getTitle().equals(title)).findFirst();
//                if(first.isPresent()){
//                    RangDto dto = first.get();
//                    dto.setNum(dto.getNum()+sum);
//                }else {
//                    RangDto dto = new RangDto();
//                    dto.setTitle(title);
//                    dto.setNum(sum);
//                    rangeDtoList.add(dto);
//                }
//            }
//        }
//
//        if(CollUtil.isNotEmpty(rangeDtoList)){
//            int sum = rangeDtoList.stream().mapToInt(RangDto::getNum).sum();
//            BigDecimal all = new BigDecimal(String.valueOf(sum));
//            BigDecimal m = new BigDecimal(rangeDtoList.stream().filter(f->"主".equals(f.getTitle())).mapToInt(RangDto::getNum).sum());
//            BigDecimal g = new BigDecimal(rangeDtoList.stream().filter(f->"客".equals(f.getTitle())).mapToInt(RangDto::getNum).sum());
//            BigDecimal l = new BigDecimal(rangeDtoList.stream().filter(f->"平".equals(f.getTitle())).mapToInt(RangDto::getNum).sum());
//            if(all.compareTo(BigDecimal.ZERO) != 0){
//                vo.setMainWin2( m.divide(all,2, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
//                vo.setLevelWin2( l.divide(all,2, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
//                vo.setGustWin2( g.divide(all,2, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
//            }
//        }
//    }
//    private void winOdds(int mainWinNum, int gustWinNum, int levelWinNum, com.ruoyi.match.match.vo.HistoryVO vo) {
//        BigDecimal m = new BigDecimal(mainWinNum);
//        BigDecimal g = new BigDecimal(gustWinNum);
//        BigDecimal l = new BigDecimal(levelWinNum);
//
//        BigDecimal all = m.add(g).add(l);
//        if(all.compareTo(BigDecimal.ZERO) != 0){
//            vo.setMainWin( m.divide(all,2, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
//            vo.setLevelWin( l.divide(all,2, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
//            vo.setGustWin( g.divide(all,2, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
//        }
//    }

//    private String getSortStr(Match match) {
//        List<SortDto> sortDtoList = Lists.newArrayList();
//
//        SortDto dto = new SortDto();
//        dto.setName("总球数0");
//        dto.setValue(match.getJq0());
//        sortDtoList.add(dto);
//
//        dto = new SortDto();
//        dto.setName("总球数1");
//        dto.setValue(match.getJq1());
//        sortDtoList.add(dto);
//
//        dto = new SortDto();
//        dto.setName("总球数2");
//        dto.setValue(match.getJq2());
//        sortDtoList.add(dto);
//
//        dto = new SortDto();
//        dto.setName("总球数3");
//        dto.setValue(match.getJq3());
//        sortDtoList.add(dto);
//
//        dto = new SortDto();
//        dto.setName("总球数4");
//        dto.setValue(match.getJq4());
//        sortDtoList.add(dto);
//
//        dto = new SortDto();
//        dto.setName("总球数5");
//        dto.setValue(match.getJq5());
//        sortDtoList.add(dto);
//
//        dto = new SortDto();
//        dto.setName("总球数6");
//        dto.setValue(match.getJq6());
//        sortDtoList.add(dto);
//
//        dto = new SortDto();
//        dto.setName("总球数大于6");
//        dto.setValue(match.getJqGt6());
//        sortDtoList.add(dto);
//        return sortDtoList.stream().sorted(Comparator.comparing(SortDto::getValue)).map(SortDto::getName).collect(Collectors.joining("->"));
//    }
//    private List<MatchSortVO> getSortList(List<Match> matches) {
//        List<MatchSortVO> sortVOList = Lists.newArrayList();
//        for (Match match : matches) {
//            String sort = getSortStr(match);
//            Optional<MatchSortVO> first = sortVOList.stream().filter(f -> f.getSortName().equals(sort)).findFirst();
//            if(first.isPresent()){
//                MatchSortVO matchSortVO = first.get();
//                matchSortVO.setNum(matchSortVO.getNum()+1);
//            }else {
//                MatchSortVO matchSortVO = new MatchSortVO();
//                matchSortVO.setSortName(sort);
//                matchSortVO.setNum(1);
//                sortVOList.add(matchSortVO);
//            }
//        }
//        return sortVOList;
//    }

    private List<SortDto> getCurrentJqSortList(Match match) {
        String matchScore = match.getMatchScore();
        int num = getJqResultByScore(matchScore);
        List<SortDto> sortDtoList = Lists.newArrayList();

        for (JqEnum value : JqEnum.values()) {
            switch (value){
                case JQ_0:
                    sortDtoList.add(getJqSortDto(value,match.getJq0(),num == value.getIndex()));
                    break;
                case JQ_1:
                    sortDtoList.add(getJqSortDto(value,match.getJq1(),num == value.getIndex()));
                    break;
                case JQ_2:
                    sortDtoList.add(getJqSortDto(value,match.getJq2(),num == value.getIndex()));
                    break;
                case JQ_3:
                    sortDtoList.add(getJqSortDto(value,match.getJq3(),num == value.getIndex()));
                    break;
                case JQ_4:
                    sortDtoList.add(getJqSortDto(value,match.getJq4(),num == value.getIndex()));
                    break;
                case JQ_5:
                    sortDtoList.add(getJqSortDto(value,match.getJq5(),num == value.getIndex()));
                    break;
                case JQ_6:
                    sortDtoList.add(getJqSortDto(value,match.getJq6(),num == value.getIndex()));
                    break;
                case JQ_gt_6:
                    sortDtoList.add(getJqSortDto(value,match.getJqGt6(),num > 6));
                    break;
            }
        }
        return sortDtoList.stream().sorted(Comparator.comparing(SortDto::getValue)).collect(Collectors.toList());

    }

    private SortDto getJqSortDto(JqEnum value, BigDecimal jq,Boolean result) {
        SortDto dto = new SortDto();
        dto.setName(value.getCode());
        dto.setValue(jq);
        dto.setResult(result);
       return dto;
    }

    private Integer getJqResultByScore(String matchScore) {
        if(matchScore.contains("其他")){
            return 7;
        }
        List<String> split = StrUtil.split(matchScore, ":");
        Integer a = Integer.valueOf(split.get(0));
        Integer b = Integer.valueOf(split.get(1));
        return a+b;
    }

    /**
     * 查询比赛信息列表
     */
    @Override
    public TableDataInfo<MatchVo> queryPageList(MatchBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Match> lqw = buildQueryWrapper(bo);
        Page<MatchVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    private List<MatchDistributionVO> getCurrentRangeList(Match match) {
        List<MatchDistributionVO> rangeList = Lists.newArrayList();
        for (CsValueEnum value : CsValueEnum.values()) {
            MatchDistributionVO vo = new MatchDistributionVO();
            vo.setType(value.getDesc());
            List<MatchDistributionNumVO> csList = getCurrentCsVo(match,value);

            vo.setCsList(csList.stream().peek(p->{
                p.setRqLabel(rqLabelHandler(p.getLabel(),match.getRq()));
                p.setJqNum(getJqResultByScore(p.getLabel()));
            }).sorted(Comparator.comparing(MatchDistributionNumVO::getPrice)).collect(Collectors.toList()));
            rangeList.add(vo);
        }
        return rangeList;
    }

    private String rqLabelHandler(String label,String rq) {
        BigDecimal rqBig = new BigDecimal(rq);
        if("胜其他".equals(label)){
            return "主";
        }else if("平其他".equals(label)){
            if(rqBig.compareTo(BigDecimal.ZERO) > 0){
                return "主";
            }else {
                return "客";
            }
        }else if("负其他".equals(label)){
            return "客";
        }else {
            List<String> split = StrUtil.split(label, ":");
            String mainJq = split.get(0);
            String gustJq = split.get(1);
            BigDecimal a = new BigDecimal(mainJq);
            BigDecimal b = new BigDecimal(gustJq);

            BigDecimal main = a.add(rqBig);

            if(main.compareTo(b) == 0){
                return "平";
            }else if(main.compareTo(b) > 0){
                return "主";
            }else {
                return "客";
            }
        }
    }

    private List<MatchDistributionNumVO> getCurrentCsVo(Match match, CsValueEnum value) {
        List<MatchDistributionNumVO> csVOList = Lists.newArrayList();
        BigDecimal min = value.getMin();
        BigDecimal max = value.getMax();

        BigDecimal cs01 = match.getCs01();
        if(cs01.compareTo(min) >= 0 && cs01.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_0_1,csVOList,cs01);
        }
        BigDecimal cs02 = match.getCs02();
        if(cs02.compareTo(min) >= 0 && cs02.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_0_2,csVOList,cs02);
        }
        BigDecimal cs03 = match.getCs03();
        if(cs03.compareTo(min) >= 0 && cs03.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_0_3,csVOList,cs03);
        }
        BigDecimal cs04 = match.getCs04();
        if(cs04.compareTo(min) >= 0 && cs04.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_0_4,csVOList,cs04);
        }
        BigDecimal cs05 = match.getCs05();
        if(cs05.compareTo(min) >= 0 && cs05.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_0_5,csVOList,cs05);
        }

        BigDecimal cs10 = match.getCs10();
        if(cs10.compareTo(min) >= 0 && cs10.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_1_0,csVOList,cs10);
        }
        BigDecimal cs12 = match.getCs12();
        if(cs12.compareTo(min) >= 0 && cs12.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_1_2,csVOList,cs12);
        }
        BigDecimal cs13 = match.getCs13();
        if(cs13.compareTo(min) >= 0 && cs13.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_1_3,csVOList,cs13);
        }

        BigDecimal cs14 = match.getCs14();
        if(cs14.compareTo(min) >= 0 && cs14.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_1_4,csVOList,cs14);
        }

        BigDecimal cs15 = match.getCs15();
        if(cs15.compareTo(min) >= 0 && cs15.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_1_5,csVOList,cs15);
        }

        BigDecimal cs20 = match.getCs20();
        if(cs20.compareTo(min) >= 0 && cs20.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_2_0,csVOList,cs20);
        }

        BigDecimal cs21 = match.getCs21();

        if(cs21.compareTo(min) >= 0 && cs21.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_2_1,csVOList,cs21);
        }

        BigDecimal cs23 = match.getCs23();
        if(cs23.compareTo(min) >= 0 && cs23.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_2_3,csVOList,cs23);
        }

        BigDecimal cs24 = match.getCs24();
        if(cs24.compareTo(min) >= 0 && cs24.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_2_4,csVOList,cs24);
        }

        BigDecimal cs25 = match.getCs25();
        if(cs25.compareTo(min) >= 0 && cs25.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_2_5,csVOList,cs25);
        }

        BigDecimal cs30 = match.getCs30();
        if(cs30.compareTo(min) >= 0 && cs30.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_3_0,csVOList,cs30);
        }

        BigDecimal cs31 = match.getCs31();
        if(cs31.compareTo(min) >= 0 && cs31.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_3_1,csVOList,cs31);
        }

        BigDecimal cs32 = match.getCs32();
        if(cs32.compareTo(min) >= 0 && cs32.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_3_2,csVOList,cs32);
        }
        BigDecimal cs40 = match.getCs40();
        if(cs40.compareTo(min) >= 0 && cs40.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_4_0,csVOList,cs40);
        }
        BigDecimal cs41 = match.getCs41();
        if(cs41.compareTo(min) >= 0 && cs41.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_4_1,csVOList,cs41);
        }

        BigDecimal cs42 = match.getCs42();
        if(cs42.compareTo(min) >= 0 && cs42.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_4_2,csVOList,cs42);
        }

        BigDecimal cs50 = match.getCs50();
        if(cs50.compareTo(min) >= 0 && cs50.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_5_0,csVOList,cs50);
        }
        BigDecimal cs51 = match.getCs51();
        if(cs51.compareTo(min) >= 0 && cs51.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_5_1,csVOList,cs51);
        }

        BigDecimal cs52 = match.getCs42();
        if(cs52.compareTo(min) >= 0 && cs52.compareTo(max) < 0){
            addCsVo(ScoreEnum.CS_5_2,csVOList,cs52);
        }

        BigDecimal level00 = match.getLevel00();
        if(level00.compareTo(min) >= 0 && level00.compareTo(max) < 0){
            addCsVo(ScoreEnum.LEVEL_0_0,csVOList,level00);
        }

        BigDecimal level11 = match.getLevel11();
        if(level11.compareTo(min) >= 0 && level11.compareTo(max) < 0){
            addCsVo(ScoreEnum.LEVEL_1_1,csVOList,level11);
        }
        BigDecimal level22 = match.getLevel22();
        if(level22.compareTo(min) >= 0 && level22.compareTo(max) < 0){
            addCsVo(ScoreEnum.LEVEL_2_2,csVOList,level22);
        }
        BigDecimal level33 = match.getLevel33();
        if(level33.compareTo(min) >= 0 && level33.compareTo(max) < 0){
            addCsVo(ScoreEnum.LEVEL_3_3,csVOList,level33);
        }

        BigDecimal winOther = match.getWinOther();
        if(winOther.compareTo(min) >= 0 && winOther.compareTo(max) < 0){
            addCsVo(ScoreEnum.WIN_OTHER,csVOList,winOther);
        }

        BigDecimal levelOther = match.getLevelOther();
        if(levelOther.compareTo(min) >= 0 && levelOther.compareTo(max) < 0){
            addCsVo(ScoreEnum.LEVEL_OTHER,csVOList,levelOther);
        }

        BigDecimal lostOther = match.getLostOther();
        if(lostOther.compareTo(min) >= 0 && lostOther.compareTo(max) < 0){
            addCsVo(ScoreEnum.LOST_OTHER,csVOList,lostOther);
        }

        return csVOList;


    }


    private void addCsVo(ScoreEnum scoreEnum, List<MatchDistributionNumVO> csVOList,BigDecimal price) {
        Optional<MatchDistributionNumVO> first = csVOList.stream().filter(f -> f.getLabel().equals(scoreEnum.getCode())).findFirst();
        if(first.isPresent()){
            MatchDistributionNumVO csVO = first.get();
            csVO.setNum(csVO.getNum()+1);
            csVO.setPrice(price);
            csVO.setResultLabel(ScoreEnum.getMatchResult(scoreEnum));
            csVO.getPriceList().add(price);
        }else {
            MatchDistributionNumVO csVO = new MatchDistributionNumVO();
            csVO.setLabel(scoreEnum.getCode());
            csVO.setNum(1);
            csVO.setPrice(price);
            csVO.setResultLabel(ScoreEnum.getMatchResult(scoreEnum));
            List<BigDecimal> priceList = new ArrayList<>();
            priceList.add(csVO.getPrice());
            csVO.setPrice(price);
            csVO.setPriceList(priceList);
            csVOList.add(csVO);
        }
    }


    /**
     * 查询比赛信息列表
     */
    @Override
    public List<MatchVo> queryList(MatchBo bo) {
        LambdaQueryWrapper<Match> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Match> buildQueryWrapper(MatchBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Match> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getMatchDate() != null, Match::getMatchDate, bo.getMatchDate());
        lqw.eq(StringUtils.isNotBlank(bo.getMatchFlag()), Match::getMatchFlag, bo.getMatchFlag());
        lqw.like(StringUtils.isNotBlank(bo.getMainTeamName()), Match::getMainTeamName, bo.getMainTeamName());
        lqw.like(StringUtils.isNotBlank(bo.getGustTeamName()), Match::getGustTeamName, bo.getGustTeamName());
        lqw.eq(StringUtils.isNotBlank(bo.getRq()), Match::getRq, bo.getRq());
        lqw.gt(bo.getMinMainWinOdds() != null, Match::getMainWinOdds, bo.getMinMainWinOdds());
        lqw.le(bo.getMaxMainWinOdds() != null, Match::getMainWinOdds, bo.getMaxMainWinOdds());
        lqw.eq(bo.getLevelOdds() != null, Match::getLevelOdds, bo.getLevelOdds());
        lqw.gt(bo.getMinGustWinOdds() != null, Match::getGustWinOdds, bo.getMinGustWinOdds());
        lqw.le(bo.getMaxGustWinOdds() != null, Match::getGustWinOdds, bo.getMaxGustWinOdds());
        lqw.gt(bo.getRqMinMainWinOdds() != null, Match::getRqMainWinOdds, bo.getRqMinMainWinOdds());
        lqw.le(bo.getRqMaxMainWinOdds() != null, Match::getRqMainWinOdds, bo.getRqMaxMainWinOdds());
        lqw.eq(bo.getRqLevelOdds() != null, Match::getRqLevelOdds, bo.getRqLevelOdds());
        lqw.gt(bo.getRqMinGustWinOdds() != null, Match::getRqGustWinOdds, bo.getRqMinGustWinOdds());
        lqw.le(bo.getRqMaxGustWinOdds() != null, Match::getRqGustWinOdds, bo.getRqMaxGustWinOdds());
        lqw.eq(bo.getCs01() != null, Match::getCs01, bo.getCs01());
        lqw.eq(bo.getCs02() != null, Match::getCs02, bo.getCs02());
        lqw.eq(bo.getCs03() != null, Match::getCs03, bo.getCs03());
        lqw.eq(bo.getCs04() != null, Match::getCs04, bo.getCs04());
        lqw.eq(bo.getCs05() != null, Match::getCs05, bo.getCs05());
        lqw.eq(bo.getCs10() != null, Match::getCs10, bo.getCs10());
        lqw.eq(bo.getCs12() != null, Match::getCs12, bo.getCs12());
        lqw.eq(bo.getCs13() != null, Match::getCs13, bo.getCs13());
        lqw.eq(bo.getCs14() != null, Match::getCs14, bo.getCs14());
        lqw.eq(bo.getCs15() != null, Match::getCs15, bo.getCs15());
        lqw.eq(bo.getCs20() != null, Match::getCs20, bo.getCs20());
        lqw.eq(bo.getCs21() != null, Match::getCs21, bo.getCs21());
        lqw.eq(bo.getCs23() != null, Match::getCs23, bo.getCs23());
        lqw.eq(bo.getCs24() != null, Match::getCs24, bo.getCs24());
        lqw.eq(bo.getCs25() != null, Match::getCs25, bo.getCs25());
        lqw.eq(bo.getCs30() != null, Match::getCs30, bo.getCs30());
        lqw.eq(bo.getCs31() != null, Match::getCs31, bo.getCs31());
        lqw.eq(bo.getCs32() != null, Match::getCs32, bo.getCs32());
        lqw.eq(bo.getCs40() != null, Match::getCs40, bo.getCs40());
        lqw.eq(bo.getCs41() != null, Match::getCs41, bo.getCs41());
        lqw.eq(bo.getCs42() != null, Match::getCs42, bo.getCs42());
        lqw.eq(bo.getCs50() != null, Match::getCs50, bo.getCs50());
        lqw.eq(bo.getCs51() != null, Match::getCs51, bo.getCs51());
        lqw.eq(bo.getCs52() != null, Match::getCs52, bo.getCs52());
        lqw.eq(bo.getLevel00() != null, Match::getLevel00, bo.getLevel00());
        lqw.eq(bo.getLevel11() != null, Match::getLevel11, bo.getLevel11());
        lqw.eq(bo.getLevel22() != null, Match::getLevel22, bo.getLevel22());
        lqw.eq(bo.getLevel33() != null, Match::getLevel33, bo.getLevel33());
        lqw.eq(bo.getLevelOther() != null, Match::getLevelOther, bo.getLevelOther());
        lqw.eq(bo.getWinOther() != null, Match::getWinOther, bo.getWinOther());
        lqw.eq(bo.getLostOther() != null, Match::getLostOther, bo.getLostOther());
        lqw.eq(bo.getJq0() != null, Match::getJq0, bo.getJq0());
        lqw.eq(bo.getJq1() != null, Match::getJq1, bo.getJq1());
        lqw.eq(bo.getJq2() != null, Match::getJq2, bo.getJq2());
        lqw.eq(bo.getJq3() != null, Match::getJq3, bo.getJq3());
        lqw.eq(bo.getJq4() != null, Match::getJq4, bo.getJq4());
        lqw.eq(bo.getJq5() != null, Match::getJq5, bo.getJq5());
        lqw.eq(bo.getJq6() != null, Match::getJq6, bo.getJq6());
        lqw.eq(bo.getJqGt6() != null, Match::getJqGt6, bo.getJqGt6());
        lqw.eq(bo.getMatchResult() != null, Match::getMatchResult, bo.getMatchResult());
        if(Objects.nonNull(bo.getRqResult())){
            if(bo.getRqResult() == 0 || bo.getRqResult() == 1 || bo.getRqResult() == 3){
                lqw.eq(Match::getRqResult, bo.getRqResult());
            }else if(bo.getRqResult() == 30){
                List<Integer> resultList = Lists.newArrayList();
                resultList.add(0);
                resultList.add(3);
                lqw.in(Match::getRqResult, resultList);
            }else if(bo.getRqResult() == 10){
                List<Integer> resultList = Lists.newArrayList();
                resultList.add(0);
                resultList.add(1);
                lqw.in(Match::getRqResult, resultList);
            }else if(bo.getRqResult() == 13 || bo.getRqResult() == 31){
                List<Integer> resultList = Lists.newArrayList();
                resultList.add(1);
                resultList.add(3);
                lqw.in(Match::getRqResult, resultList);
            }
        }

        lqw.eq(StringUtils.isNotBlank(bo.getMatchScore()), Match::getMatchScore, bo.getMatchScore());
        lqw.orderByAsc(Match::getMatchScore);
        return lqw;
    }

    /**
     * 新增比赛信息
     */
    @Override
    public Boolean insertByBo(MatchBo bo) {
        Match add = BeanUtil.toBean(bo, Match.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改比赛信息
     */
    @Override
    public Boolean updateByBo(MatchBo bo) {
        Match update = BeanUtil.toBean(bo, Match.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Match entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除比赛信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }


}
